//
//  WmcImage.swift
//  YPWatermarkCamera
//
//  Created by 赵新 on 2022/3/1.
//

import UIKit
import YPBedrock

public extension WmcImage {
    /// 图片的加载类型
    enum ImageType {
        /// 无
        case none
        /// 通过图片名加载
        case name(_ name: String)
        /// 通过图片名加载
        case uiImage(_ uiImage: UIImage)
        /// 通过数据加载
        case data(_ data: Data)
        /// 通过Url加载
        case url(_ url: YPUnifiedUrl)
        /// 通过文件路径加载
        case filePath(_ filePath: String)
        /// base64字符串
        case base64String(_ base64String: String)

        var description: String {
            switch self {
            case .none: return "⚠️None！"
            case let .name(value): return "🌄Assets: \(value)"
            case let .uiImage(value): return "🎆UIImage: \(value.description)"
            case let .data(value): return "💾Data: \(value.description)"
            case let .url(value): return "🔗Url: \(value)"
            case let .filePath(value): return "🗃FilePath: \(value.description)"
            case .base64String: return "🔑Base64String"
            }
        }
    }
}

// MARK: - [WmcImage]

open class WmcImage: WmcMedia {
    // Lifecycle

    override public init() {
        super.init()
    }

    /// 通过图片名加载
    public convenience init(name: String) {
        self.init()
        imageType = .name(name)
    }

    /// 通过图片加载
    public convenience init(uiImage: UIImage) {
        self.init()
        imageType = .uiImage(uiImage)
    }

    /// 通过数据加载
    public convenience init(data: Data) {
        self.init()
        imageType = .data(data)
    }

    /// 通过Url加载
    public convenience init(url: YPUnifiedUrl) {
        self.init()
        imageType = .url(url)
    }

    /// 通过文件路径加载
    public convenience init(filePath: String) {
        self.init()
        imageType = .filePath(filePath)
    }

    /// 通过base64字符串加载
    public convenience init(base64String: String) {
        self.init()
        imageType = .base64String(base64String)
    }

    // Open

    /// 图片类型枚举
    open var imageType: ImageType = .none

    override open var description: String {
        let supDes = super.description
        return "\(supDes): \(imageType.description)"
    }

    /// 唯一值
    open var hashKey: String {
        switch imageType {
        case .none:
            return ""
        case let .name(name):
            return name
        case let .uiImage(image):
            return image.hashValue.yp.string
        case let .data(data):
            return data.hashValue.yp.string
        case let .url(url):
            return String.YP.Create(url).yp.hashStr(.md5) ?? ""
        case let .filePath(path):
            return path.yp.hashStr(.md5) ?? ""
        case let .base64String(str):
            return "\(str.hashValue)"
        }
    }

    open func loadUIImage(successBlock: @escaping YPBlock.OneParam<UIImage>,
                          failureBlock: YPBlock.OneParam<YPWmcError>? = nil)
    {
        switch imageType {
        case .none:
            let _log = "图片类型为none，无法加载"
            log(_log)
            failureBlock?(.init(errorType: .actionError, info: _log))

        case let .name(name):
            if let image = UIImage(named: name, in: .WmcBundle, compatibleWith: nil) {
                successBlock(image)
            } else {
                let _log = "图片名称读取错误！请图片名称是否正确！"
                log(_log)
                failureBlock?(.init(errorType: .parsingError, info: _log))
            }

        case let .uiImage(uiImage):
            successBlock(uiImage)

        case let .data(data):
            if let image = data.yp.uiImage {
                successBlock(image)
            } else {
                let _log = "图片数据错误！请图片数据是否正确！"
                log(_log)
                failureBlock?(.init(errorType: .parsingError, info: _log))
            }

        case let .url(url):
            let _url = URL.YP.Create(url)
            let imageView = UIImageView()
            imageView.kf.setImage(with: _url, options: [.forceTransition], completionHandler: { res in
                // 这里如果使用weakSelf，会导致无法执行，WmcImage可能会被释放
                switch res {
                case .success:
                    if let image = imageView.image {
                        successBlock(image)
                    } else {
                        let _log = "图片地址错误！请图片地址是否正确！"
                        WmcLogManager.DebugLog(type: .wmcImage, log: _log)
                        failureBlock?(.init(errorType: .parsingError, info: _log))
                    }
                case let .failure(err):
                    let _log = err.localizedDescription
                    WmcLogManager.DebugLog(type: .wmcImage, log: _log)
                    failureBlock?(.init(errorType: .parsingError, info: _log))
                }
            })

        case let .filePath(path):
            var imagePath = path
            if !path.hasPrefix(YPSystem.Documents.Path) {
                imagePath = YPSystem.Documents.Path
                    .yp.appendPathComponent(imagePath)
            }
            if let image = UIImage(contentsOfFile: imagePath) {
                successBlock(image)
            } else {
                let _log = "图片文件读取错误！请检查路径是否正确！\(path)"
                log(_log)
                failureBlock?(.init(errorType: .parsingError, info: _log))
            }

        case let .base64String(str):
            if let image = str.yp.base64Image {
                successBlock(image)
            } else {
                log("Base64转图片错误！请检查字符串是否正确！\(str)")
            }
        }
    }

    // Internal

    open override func mediaType() -> WmcMedia.MediaType {
        return .image
    }

    // Fileprivate

    fileprivate static var loadQueue : DispatchQueue = .init(label: "com.wmc.WmcImage")
    
    /// 日志系统
    fileprivate func log(_ log: String) {
        WmcLogManager.DebugLog(type: .wmcImage, log: log)
    }
}
